/*
 * 热点管理模块
 *
 * 对备份文件进行检测和热点管理
 *
 **/

#pragma once

#include <functional>
#include <thread>
#include "info.hh"
#include "data.hh"
#include "task.hh"
#include "cpmodel.hh"

namespace cloud
{
    class hot_manager
    {
    public:
        static hot_manager& instance()
        {
            static hot_manager hm;
            return hm;
        }

    private:
        hot_manager()
            : _data_mgr(data_manager::instance())
            , _cp_model(cp_model::instance())
        {
            util::dir(config::instance().back_dir()).create();
            util::dir(config::instance().pack_dir()).create();

            easylog::info("hot manager created");
        }

        hot_manager(const hot_manager&) = delete;
        hot_manager& operator=(const hot_manager&) = delete;

    public:
        void run()
        {
            _detector = std::thread(&hot_manager::detect, this);
            _detector.detach();
        }

        void detect()
        {
            while (true)
            {
                std::vector<std::string> paths =
                        util::dir(config::instance().back_dir()).rscan();

                for (auto& p : paths)
                {
                    if (util::path::isdir(p))
                        continue;

                    backup_info* info = _data_mgr.get_by_bpath(p);

                    if (info && info->ishot)
                    {
                        info->mtime = util::file(p).mtime();

                        if (util::time::now() - info->mtime > config::instance().hot_time())
                        {
                            task::ptr pt = task_factory::create<pack_task>(info);
                            _cp_model.push(pt);

                            easylog::debug("pack a file succ {}", info->bpath);
                        }
                    }
                }

                std::this_thread::sleep_for(std::chrono::seconds(1));
            }
        }

    private:
        data_manager& _data_mgr;
        cp_model& _cp_model;
        std::thread _detector;
    };
}
